int xc_bvtsched_domain_set(int xc_handle,
u32 domid,
- unsigned long mcuadv,
- unsigned long warp,
- unsigned long warpl,
- unsigned long warpu);
+ u32 mcuadv,
+ int warpback,
+ s32 warpvalue,
+ long long warpl,
+ long long warpu);
int xc_bvtsched_global_get(int xc_handle,
unsigned long *ctx_allow);
int xc_bvtsched_domain_get(int xc_handle,
u32 domid,
- unsigned long *mcuadv,
- unsigned long *warp,
- unsigned long *warpl,
- unsigned long *warpu);
+ u32 *mcuadv,
+ int *warpback,
+ s32 *warpvalue,
+ long long *warpl,
+ long long *warpu);
int xc_fbvtsched_global_set(int xc_handle,
unsigned long ctx_allow);
int xc_bvtsched_domain_set(int xc_handle,
u32 domid,
- unsigned long mcuadv,
- unsigned long warp,
- unsigned long warpl,
- unsigned long warpu)
+ u32 mcuadv,
+ int warpback,
+ s32 warpvalue,
+ long long warpl,
+ long long warpu)
{
dom0_op_t op;
struct bvt_adjdom *bvtadj = &op.u.adjustdom.u.bvt;
op.u.adjustdom.sched_id = SCHED_BVT;
op.u.adjustdom.direction = SCHED_INFO_PUT;
- bvtadj->mcu_adv = mcuadv;
- bvtadj->warp = warp;
- bvtadj->warpl = warpl;
- bvtadj->warpu = warpu;
+ bvtadj->mcu_adv = mcuadv;
+ bvtadj->warpback = warpback;
+ bvtadj->warpvalue = warpvalue;
+ bvtadj->warpl = warpl;
+ bvtadj->warpu = warpu;
return do_dom0_op(xc_handle, &op);
}
int xc_bvtsched_domain_get(int xc_handle,
u32 domid,
- unsigned long *mcuadv,
- unsigned long *warp,
- unsigned long *warpl,
- unsigned long *warpu)
+ u32 *mcuadv,
+ int *warpback,
+ s32 *warpvalue,
+ long long *warpl,
+ long long *warpu)
{
dom0_op_t op;
ret = do_dom0_op(xc_handle, &op);
- *mcuadv = adjptr->mcu_adv;
- *warp = adjptr->warp;
- *warpl = adjptr->warpl;
- *warpu = adjptr->warpu;
+ *mcuadv = adjptr->mcu_adv;
+ *warpback = adjptr->warpback;
+ *warpvalue = adjptr->warpvalue;
+ *warpl = adjptr->warpl;
+ *warpu = adjptr->warpu;
return ret;
}
{
XcObject *xc = (XcObject *)self;
- u32 dom;
- unsigned long mcuadv, warp, warpl, warpu;
-
- static char *kwd_list[] = { "dom", "mcuadv", "warp", "warpl",
- "warpu", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illll", kwd_list,
- &dom, &mcuadv, &warp, &warpl, &warpu) )
+ u32 dom;
+ u32 mcuadv;
+ int warpback;
+ s32 warpvalue;
+ long long warpl;
+ long long warpu;
+
+ static char *kwd_list[] = { "dom", "mcuadv", "warpback", "warpvalue",
+ "warpl", "warpu", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiill", kwd_list,
+ &dom, &mcuadv, &warpback, &warpvalue,
+ &warpl, &warpu) )
return NULL;
if ( xc_bvtsched_domain_set(xc->xc_handle, dom, mcuadv,
- warp, warpl, warpu) != 0 )
+ warpback, warpvalue, warpl, warpu) != 0 )
return PyErr_SetFromErrno(xc_error);
Py_INCREF(zero);
{
XcObject *xc = (XcObject *)self;
u32 dom;
- unsigned long mcuadv, warp, warpl, warpu;
+ u32 mcuadv;
+ int warpback;
+ s32 warpvalue;
+ long long warpl;
+ long long warpu;
static char *kwd_list[] = { "dom", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
return NULL;
- if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warp,
- &warpl, &warpu) != 0 )
+ if ( xc_bvtsched_domain_get(xc->xc_handle, dom, &mcuadv, &warpback,
+ &warpvalue, &warpl, &warpu) != 0 )
return PyErr_SetFromErrno(xc_error);
return Py_BuildValue("{s:i,s:l,s:l,s:l,s:l}",
"domain", dom,
"mcuadv", mcuadv,
- "warp", warp,
- "warpl", warpl,
- "warpu", warpu);
+ "warpback", warpback,
+ "warpvalue", warpvalue,
+ "warpl", warpl,
+ "warpu", warpu);
}
static PyObject *pyxc_fbvtsched_global_set(PyObject *self,
(PyCFunction)pyxc_bvtsched_domain_set,
METH_VARARGS | METH_KEYWORDS, "\n"
"Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
- " dom [int]: Identifier of domain to be tuned.\n"
- " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
- " warp [int]: How far to warp domain's EVT on unblock.\n"
- " warpl [int]: How long the domain can run warped.\n"
- " warpu [int]: How long before the domain can warp again.\n\n"
- "Returns: [int] 0 on success; -1 on error.\n" },
+ " dom [int]: Identifier of domain to be tuned.\n"
+ " mcuadv [int]: Proportional to the inverse of the domain's weight.\n"
+ " warpback [int]: Warp ? \n"
+ " warpvalue [int]: How far to warp domain's EVT on unblock.\n"
+ " warpl [int]: How long the domain can run warped.\n"
+ " warpu [int]: How long before the domain can warp again.\n\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
{ "bvtsched_domain_get",
(PyCFunction)pyxc_bvtsched_domain_get,
{'op' : 'pincpu',
'cpu' : cpu })
- def xend_domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu):
+ def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, warpu):
return self.xendPost(self.domainurl(id),
- {'op' : 'cpu_bvt_set',
- 'mcuadv' : mcuadv,
- 'warp' : warp,
- 'warpl' : warpl,
- 'warpu' : warpu })
+ {'op' : 'cpu_bvt_set',
+ 'mcuadv' : mcuadv,
+ 'warpback' : warpback,
+ 'warpvalue': warpvalue,
+ 'warpl' : warpl,
+ 'warpu' : warpu })
def xend_domain_cpu_fbvt_set(self, id, mcuadv, warp, warpl, warpu):
return self.xendPost(self.domainurl(id),
except Exception, ex:
raise XendError(str(ex))
- def domain_cpu_bvt_set(self, id, mcuadv, warp, warpl, warpu):
+ def domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, warpu):
"""Set BVT (Borrowed Virtual Time) scheduler parameters for a domain.
"""
dominfo = self.domain_lookup(id)
try:
return xc.bvtsched_domain_set(dom=dominfo.dom, mcuadv=mcuadv,
- warp=warp, warpl=warpl, warpu=warpu)
+ warpback=warpback, warpvalue=warpvalue,
+ warpl=warpl, warpu=warpu)
except Exception, ex:
raise XendError(str(ex))
fn = FormFn(self.xd.domain_cpu_bvt_set,
[['dom', 'str'],
['mcuadv', 'int'],
- ['warp', 'int'],
+ ['warpback', 'int'],
+ ['warpvalue', 'int'],
['warpl', 'int'],
['warpu', 'int']])
val = fn(req.args, {'dom': self.dom.name})
info = """Set BVT scheduler parameters."""
def help(self, args):
- print args[0], "DOM MCUADV WARP WARPL WARPU"
+ print args[0], "DOM MCUADV WARPBACK WARPVALUE WARPL WARPU"
print '\nSet Borrowed Virtual Time scheduler parameters.'
def main(self, args):
- if len(args) != 6: self.err("%s: Invalid argument(s)" % args[0])
- v = map(int, args[1:6])
+ if len(args) != 7: self.err("%s: Invalid argument(s)" % args[0])
+ v = map(int, args[1:7])
server.xend_domain_cpu_bvt_set(*v)
xm.prog(ProgBvt)
{
struct domain *domain; /* domain this info belongs to */
struct list_head run_list; /* runqueue list pointers */
- unsigned long mcu_advance; /* inverse of weight */
+ u32 mcu_advance; /* inverse of weight */
u32 avt; /* actual virtual time */
u32 evt; /* effective virtual time */
int warpback; /* warp? */
- long warp; /* virtual time warp */
- long warpl; /* warp limit */
- long warpu; /* unwarp time requirement */
- s_time_t warped; /* time it ran warped last time */
- s_time_t uwarped; /* time it ran unwarped last time */
+ int warp; /* warp set and within the warp
+ limits*/
+ s32 warp_value; /* virtual time warp */
+ s_time_t warpl; /* warp limit */
+ struct ac_timer warp_timer; /* deals with warpl */
+ s_time_t warpu; /* unwarp time requirement */
+ struct ac_timer unwarp_timer; /* deals with warpu */
};
struct bvt_cpu_info
return (RUNLIST(d))->next != NULL;
}
+
+/* Warp/unwarp timer functions */
+static void warp_timer_fn(unsigned long pointer)
+{
+ struct bvt_dom_info *inf = (struct bvt_dom_info *)pointer;
+
+printk("--> Warp timer fired for %d\n", inf->domain->domain);
+ inf->warp = 0;
+ /* unwarp equal to zero => stop warping */
+ if(inf->warpu == 0)
+ {
+ inf->warpback = 0;
+ goto reschedule;
+ }
+
+ /* set unwarp timer */
+ inf->unwarp_timer.expires = NOW() + inf->warpu;
+ add_ac_timer(&inf->unwarp_timer);
+
+reschedule:
+ cpu_raise_softirq(inf->domain->processor, SCHEDULE_SOFTIRQ);
+}
+
+static void unwarp_timer_fn(unsigned long pointer)
+{
+ struct bvt_dom_info *inf = (struct bvt_dom_info *)pointer;
+
+printk("---> UnWarp timer fired for %d\n", inf->domain->domain);
+ if(inf->warpback)
+ {
+ inf->warp = 1;
+ cpu_raise_softirq(inf->domain->processor, SCHEDULE_SOFTIRQ);
+ }
+}
+
+
+
static inline u32 calc_avt(struct domain *d, s_time_t now)
{
u32 ranfor, mcus;
struct bvt_dom_info *inf = BVT_INFO(d);
/* TODO The warp routines need to be rewritten GM */
- if ( inf->warpback )
- return avt - inf->warp;
+ if ( inf->warp )
+ return avt - inf->warp_value;
else
return avt;
}
inf->mcu_advance = MCU_ADVANCE;
inf->domain = p;
+ inf->warpback = 0;
+ /* Set some default values here. */
+ inf->warp = 0;
+ inf->warp_value = 0;
+ inf->warpl = MILLISECS(2000);
+ inf->warpu = MILLISECS(1000);
+ /* initialise the timers */
+ init_ac_timer(&inf->warp_timer);
+ inf->warp_timer.cpu = p->processor;
+ inf->warp_timer.data = (unsigned long)inf;
+ inf->warp_timer.function = &warp_timer_fn;
+ init_ac_timer(&inf->unwarp_timer);
+ inf->unwarp_timer.cpu = p->processor;
+ inf->unwarp_timer.data = (unsigned long)inf;
+ inf->unwarp_timer.function = &unwarp_timer_fn;
if ( p->domain == IDLE_DOMAIN_ID )
{
/* Set avt and evt to system virtual time. */
inf->avt = CPU_SVT(p->processor);
inf->evt = CPU_SVT(p->processor);
- /* Set some default values here. */
- inf->warpback = 0;
- inf->warp = 0;
- inf->warpl = 0;
- inf->warpu = 0;
- }
+ }
return;
}
*/
static void bvt_do_block(struct domain *p)
{
- BVT_INFO(p)->warpback = 0;
+ // TODO what when blocks? BVT_INFO(p)->warpback = 0;
}
/* Control the scheduler. */
if ( cmd->direction == SCHED_INFO_PUT )
{
- unsigned long mcu_adv = params->mcu_adv,
- warp = params->warp,
- warpl = params->warpl,
- warpu = params->warpu;
+ u32 mcu_adv = params->mcu_adv;
+ u32 warpback = params->warpback;
+ s32 warpvalue = params->warpvalue;
+ s_time_t warpl = params->warpl;
+ s_time_t warpu = params->warpu;
struct bvt_dom_info *inf = BVT_INFO(p);
- DPRINTK("Get domain %u bvt mcu_adv=%ld, warp=%ld, "
+ DPRINTK("Get domain %u bvt mcu_adv=%u, warpback=%d, warpvalue=%d"
"warpl=%ld, warpu=%ld\n",
- p->domain, inf->mcu_advance, inf->warp,
+ p->domain, inf->mcu_advance, inf->warpback, inf->warpvalue,
inf->warpl, inf->warpu );
/* Sanity -- this can avoid divide-by-zero. */
spin_lock_irqsave(&CPU_INFO(p->processor)->run_lock, flags);
inf->mcu_advance = mcu_adv;
- inf->warp = warp;
+ inf->warpback = warpback; // TODO - temporary
+ inf->warp = 1;
+ inf->warp_value = warpvalue;
inf->warpl = warpl;
inf->warpu = warpu;
- DPRINTK("Set domain %u bvt mcu_adv=%ld, warp=%ld, "
+ DPRINTK("Get domain %u bvt mcu_adv=%u, warpback=%d, warpvalue=%d"
"warpl=%ld, warpu=%ld\n",
- p->domain, inf->mcu_advance, inf->warp,
+ p->domain, inf->mcu_advance, inf->warpback, inf->warpvalue,
inf->warpl, inf->warpu );
spin_unlock_irqrestore(&CPU_INFO(p->processor)->run_lock, flags);
struct bvt_dom_info *inf = BVT_INFO(p);
spin_lock_irqsave(&CPU_INFO(p->processor)->run_lock, flags);
- params->mcu_adv = inf->mcu_advance;
- params->warp = inf->warp;
- params->warpl = inf->warpl;
- params->warpu = inf->warpu;
+ params->mcu_adv = inf->mcu_advance;
+ params->warpvalue = inf->warp_value;
+ params->warpback = inf->warpback;
+ params->warpl = inf->warpl;
+ params->warpu = inf->warpu;
spin_unlock_irqrestore(&CPU_INFO(p->processor)->run_lock, flags);
}
{
prev_inf->avt = calc_avt(prev, now);
prev_inf->evt = calc_evt(prev, prev_inf->avt);
-
+
+ rem_ac_timer(&prev_inf->warp_timer);
__del_from_runqueue(prev);
if ( domain_runnable(prev) )
ASSERT(r_time >= ctx_allow);
sched_done:
+ if(next_inf->warp && next_inf->warpl > 0) // TODO - already added?
+ {
+ /* Set the timer up */
+ next_inf->warp_timer.expires = now + next_inf->warpl;
+ /* Add it to the heap */
+ add_ac_timer(&next_inf->warp_timer);
+ }
ret.task = next;
ret.time = r_time;
return ret;
{
struct bvt_dom_info *inf = BVT_INFO(p);
- printk("mcua=0x%04lX ev=0x%08X av=0x%08X ",
+ printk("mcua=%d ev=0x%08X av=0x%08X ",
inf->mcu_advance, inf->evt, inf->avt);
}
/* We use cache to create the bvt_dom_infos
this functions makes sure that the run_list
- is initialised properly. The new domain needs
- NOT to appear as to be on the runqueue */
+ is initialised properly.
+ Call to __task_on_runqueue needs to return false */
static void cache_constructor(void *arg1, xmem_cache_t *arg2, unsigned long arg3)
{
struct bvt_dom_info *dom_inf = (struct bvt_dom_info*)arg1;
union { /* 16 */
struct bvt_adjdom
{
- u32 mcu_adv; /* 16: mcu advance: inverse of weight */
- u32 warp; /* 20: time warp */
- u32 warpl; /* 24: warp limit */
- u32 warpu; /* 28: unwarp time requirement */
+ u32 mcu_adv; /* 16: mcu advance: inverse of weight */
+ u32 warpback; /* 20: warp? */
+ s32 warpvalue; /* 24: warp value */
+ long long warpl; /* 32: warp limit */
+ long long warpu; /* 40: unwarp time requirement */
} PACKED bvt;
struct fbvt_adjdom